﻿using System.ComponentModel;
using Loki.Commands;
using Loki.Utils;
using Luna.Connectors;

namespace Luna.UI.Configuration
{
    public abstract class ConnectorViewModel : LunaViewModel
    {
        public abstract ConnectorType Type { get; }

        public ICommand Test { get; private set; }

        public ICommand Save { get; private set; }

        #region Login

        private static PropertyChangedEventArgs _LoginChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorViewModel>(x => x.Login);

        private static PropertyChangingEventArgs _LoginChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorViewModel>(x => x.Login);

        private string _Login;

        public string Login
        {
            get
            {
                return _Login;
            }

            set
            {
                if (value != _Login)
                {
                    NotifyChanging(_LoginChangingArgs);
                    _Login = value;
                    NotifyChangedAndDirty(_LoginChangedArgs);
                }
            }
        }

        #endregion Login

        #region Password

        private static PropertyChangedEventArgs _PasswordChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorViewModel>(x => x.Password);

        private static PropertyChangingEventArgs _PasswordChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorViewModel>(x => x.Password);

        private string _Password;

        public string Password
        {
            get
            {
                return _Password;
            }

            set
            {
                if (value != _Password)
                {
                    NotifyChanging(_PasswordChangingArgs);
                    _Password = value;
                    NotifyChangedAndDirty(_PasswordChangedArgs);
                }
            }
        }

        #endregion Password

        #region Enabled

        private static PropertyChangedEventArgs _EnabledChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorViewModel>(x => x.Enabled);

        private static PropertyChangingEventArgs _EnabledChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorViewModel>(x => x.Enabled);

        private bool _Enabled;

        public bool Enabled
        {
            get
            {
                return _Enabled;
            }

            set
            {
                if (value != _Enabled)
                {
                    NotifyChanging(_EnabledChangingArgs);
                    _Enabled = value;
                    NotifyChanged(_EnabledChangedArgs);
                }
            }
        }

        #endregion Enabled

        #region Name

        private static PropertyChangedEventArgs _NameChangedArgs = ObservableHelper.CreateChangedArgs<ConnectorViewModel>(x => x.Name);

        private static PropertyChangingEventArgs _NameChangingArgs = ObservableHelper.CreateChangingArgs<ConnectorViewModel>(x => x.Name);

        private string _Name;

        public string Name
        {
            get
            {
                return _Name;
            }

            set
            {
                if (value != _Name)
                {
                    NotifyChanging(_NameChangingArgs);
                    _Name = value;
                    NotifyChanged(_NameChangedArgs);
                }
            }
        }

        #endregion Name

        public ConnectorViewModel()
        {
            Load += ConnectorViewModel_Load;
            Init += ConnectorViewModel_Init;
            DisplayName = "Connector";

            Test = Commands.Create();
            Save = Commands.Create();
        }

        private void ConnectorViewModel_Init(object P_Sender, System.EventArgs e)
        {
            Commands.Handle(Test, Test_Execute);
            Commands.Handle(Save, Save_Execute);

            ApplicationModel.Configuration.DatabaseChanged += Configuration_DatabaseChanged;
        }

        private void Configuration_DatabaseChanged(object P_Sender, System.EventArgs e)
        {
            /*/ IConnectorConfiguration L_Config = ApplicationModel.Configuration.ConnectorConfigurations[Type];
             LoadValues(L_Config);*/

            AcceptChanges();
        }

        private void Save_Execute(object P_Sender, CommandEventArgs e)
        {
            IConnectorConfiguration L_Config = ApplicationModel.Configuration.ConnectorConfigurations[Type];
            ReadValues(L_Config);

            ApplicationModel.Configuration.Configure(L_Config);

            L_Config = ApplicationModel.Configuration.ConnectorConfigurations[Type];
            LoadValues(L_Config);

            AcceptChanges();
        }

        protected virtual void ReadValues(IConnectorConfiguration P_Configuration)
        {
            P_Configuration.Login = Login;
            P_Configuration.Password = Password;
        }

        protected virtual void LoadValues(IConnectorConfiguration P_Configuration)
        {
            Login = P_Configuration.Login;
            Password = P_Configuration.Password;
            Enabled = P_Configuration.Enabled;
            Name = P_Configuration.Name;
        }

        private void Test_Execute(object P_Sender, CommandEventArgs e)
        {
            IConnectorConfiguration L_Config = ApplicationModel.Configuration.ConnectorConfigurations[Type];
            ReadValues(L_Config);

            string L_Return = ApplicationModel.Configuration.Test(L_Config);
            if (L_Return == string.Empty)
            {
                UserMessage("Success");
            }
            else
            {
                UserWarning(L_Return);
            }
        }

        private void ConnectorViewModel_Load(object P_Sender, System.EventArgs e)
        {
            /* IConnectorConfiguration L_Config = ApplicationModel.Configuration.ConnectorConfigurations[Type];
             Login = L_Config.Login;
             Password = L_Config.Password;
             Enabled = L_Config.Enabled;
             Name = L_Config.Name;*/

            AcceptChanges();
        }
    }
}